package com.top10.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.top10.bean.ResponseBean;
import com.top10.bean.alipay.AlipayConfig;
import com.top10.common.AliPayConst;
import com.top10.common.Const;
import com.top10.entity.*;
import com.top10.entity.vo.UserCartGoodsVo;
import com.top10.service.*;
import com.top10.utils.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**支付宝支付
 * @author sny
 * @Package com.top10.controller
 * @date 2018/11/12
 */
@RestController
@RequestMapping("/top10/ali")
public class AliPayController {
    private static final Logger logger = LoggerFactory.getLogger("system");

    @Autowired
    private IOrderService iOrderService;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private IUserDepositService iUserDepositService;
    @Autowired
    IUserCartService userCartService;
    @Autowired
    private IOrderDetailedService iOrderDetailedService;
    @Autowired
    private IGoodsDetailedService iGoodsDetailedService;


    //配置初始化信息参数
    public static DefaultAlipayClient alipayclient(){
        DefaultAlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL,
                AlipayConfig.APPID,
                AlipayConfig.RSA_PRIVATE_KEY,
                "json", "utf-8",
                AlipayConfig.ALIPAY_PUBLIC_KEY,
                "RSA2");
        return alipayClient;
    }


    @PostMapping("/test")
    public ResponseBean test(){
        return ResponseBean.createError("testtest");
    }


    /***
     * 商品订单支付
     * @param payid
     * @return
     * @throws AlipayApiException
     */
    @PostMapping("/pay")
    public ResponseBean pay(String payid,Long type) throws AlipayApiException {

        if (type == null || "".equals(type)) {
            return ResponseBean.createError("支付类型不能为空");
        }

        double actualPrice=0;
        if(type==1) {
            if (payid == null || "".equals(payid)) {
                return ResponseBean.createError("订单号不能为空");
            }

            List<Order> orders = iOrderService.selectList(new EntityWrapper<Order>().eq("payid", payid));
            if (orders == null) {
                return ResponseBean.createError("不存在该订单，支付发生错误");
            }

            for (Order order : orders) {
                actualPrice += order.getActualPrice();
            }


        }

        if(type==2){

            if (payid == null || "".equals(payid)) {
                return ResponseBean.createError("充值订单号不能为空");
            }

            UserDeposit userDeposit=iUserDepositService.selectOne(new EntityWrapper<UserDeposit>().eq("order_sn",payid));
            if(userDeposit==null){
                return ResponseBean.createError("不存在该信息，充值发生错误");
            }
            actualPrice=userDeposit.getMoney().doubleValue();
        }

        BigDecimal bd = new BigDecimal(actualPrice);
        double d = bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

        AlipayClient aliClient=alipayclient();
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        //  model.setBody("测试支付");
        model.setSubject("顶十商城");

        model.setOutTradeNo(String.valueOf(payid));
        //超时时间

        //  model.setTimeoutExpress("30000m");
        model.setTotalAmount(String.valueOf(d));
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(AlipayConfig.notify_url);
        //这里和普通的接口调用不同，使用的是sdkExecute
        AlipayTradeAppPayResponse response = aliClient.sdkExecute(request);
        String orderStr=response.getBody();
        System.out.println(response.getBody());
        System.out.println(actualPrice);
        return ResponseBean.createSuccess().addData("response",response).addData("actualPrice",actualPrice);
    }


    /*  http://112.74.208.66:8999/top10-app/tlzf/tlnotify.action

	  http://112.74.208.66:8999/top10-app/top10/ali/notify_url.action
  */
    @PostMapping("/notify_url")
    public Object alipayCallback(HttpServletRequest request){
        Map<String,String> params = new HashMap<>();

        Map requestParams = request.getParameterMap();
        for(Iterator iter = requestParams.keySet().iterator(); iter.hasNext();){
            String name = (String)iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for(int i = 0 ; i <values.length;i++){

                valueStr = (i == values.length -1)?valueStr + values[i]:valueStr + values[i]+",";
            }
            params.put(name,valueStr);
        }
        params.remove("sign_type");
        try {
            boolean alipayRSACheckedV2 = AlipaySignature.rsaCheckV2(params,  AlipayConfig.ALIPAY_PUBLIC_KEY,"utf-8","RSA2");

            if(!alipayRSACheckedV2){
                logger.error("支付错误");
                return ResponseBean.createError("支付错误");
            }
        } catch (AlipayApiException e) {

        }

        //校验
        String payid = params.get("out_trade_no");
        // String tradeNo = params.get("trade_no");
        String tradeStatus = params.get("trade_status");
        //交易成功
        if(AliPayConst.TRADE_STATUS_TRADE_SUCCESS.equals(tradeStatus)){

            List<Order> orders=iOrderService.selectList(new EntityWrapper<Order>().eq("payid",payid));
            if(orders.size()!=0) {
                for (Order order : orders) {
                    //设置该订单支付类型为：支付宝支付
                    order.setPaytype(AliPayConst.PAY_TYPE_ALI);
                    //修改该订单状态为 ：待发货
                    order.setStatus(AliPayConst.ORDER_WAIT_STATUS);
                    //旧的状态为待支付
                    order.setOldStatus(7);
                    order.setUpdatetime(new Date());
                    iOrderService.updateById(order);
                    //购物车清理的问题
                    UserCartGoodsVo goods=iOrderDetailedService.selectGoods(order.getId());
                    if(goods != null){
                        if(goods.getAttributes().equals("{}") || goods.getAttributes()==null){
                            userCartService.delete(new EntityWrapper<UserCart>().eq("user_uuid",order.getUserUuid()).eq("goods_uuid",goods.getGoods_uuid()).eq("isdeleted",false));
                        }else{
                            userCartService.delete(new EntityWrapper<UserCart>().eq("user_uuid",order.getUserUuid()).eq("goods_uuid",goods.getGoods_uuid()).eq("attributes",goods.getAttributes()).eq("ideleted",false));
                        }
                    }

                    //销量增加
                    List<OrderDetailed> orderDetailedsLists=iOrderDetailedService.selectList(new EntityWrapper<OrderDetailed>().eq("order_uuid",order.getUuid()));
                    for(OrderDetailed orderDetailedList:orderDetailedsLists) {
                        GoodsDetailed goodsDetailed = iGoodsDetailedService.selectOne(new EntityWrapper<GoodsDetailed>().eq("uuid", orderDetailedList.getGoodsDetailedUuid()));
                        goodsDetailed.setSoldQuantity(goodsDetailed.getSoldQuantity()+orderDetailedList.getQuantity());
                        iGoodsDetailedService.updateById(goodsDetailed);
                    }



                }

                return AliPayConst.SUCCESS;
            }

            UserDeposit userDeposit=iUserDepositService.selectOne(new EntityWrapper<UserDeposit>().eq("order_sn",payid));
            if(userDeposit==null){
                return AliPayConst.FAILED;

            }
            User user=iUserService.selectOne(new EntityWrapper<User>().eq("uuid",userDeposit.getUid()));
            user.setMoney(user.getMoney().add(userDeposit.getMoney()));
            userDeposit.setOrderStatus(1);
            userDeposit.setTradeTime(new Date());
            iUserDepositService.updateById(userDeposit);
            iUserService.updateById(user);
            return AliPayConst.SUCCESS;

        }

        return AliPayConst.FAILED;
    }


    /**
     *
     * @param out_trade_no       商品交易订单号

     *
     * @return
     */
    @PostMapping("/refund")
    public ResponseBean refund(String out_trade_no,String orderId){



        if((out_trade_no==null||"".equals(out_trade_no))){
            return ResponseBean.createError("商品订单号不能为空");
        }
        String returnStr = null;

        //支付宝交易号
        String trade_no=null;
        //订单价格
        double refund_amount=0;

        Order order=iOrderService.selectOne(new EntityWrapper<Order>().eq("orderid",orderId));
        if(order==null){
            return ResponseBean.createError("不存在该订单");
        }

        refund_amount=order.getActualPrice();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String refundId = sdf.format(new Date()) + RandomUtils.makeRandomDigit6() + RandomUtils.getNBitRandomDigit(4);

        String out_request_no = refundId;// 不是全额退款，部分退款使用该参数
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, "RSA2");
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            request.setBizContent("{" +
                    "\"out_trade_no\":\"" + out_trade_no + "\"," +
                    "\"trade_no\":\"" + trade_no + "\"," +
                    "\"refund_amount\":\"" + refund_amount + "\"," +
                    "\"out_request_no\":\"" + out_request_no + "\"," +
                    "\"refund_reason\":\"正常退款\"" +
                    " }");
            AlipayTradeRefundResponse response;
            response = alipayClient.execute(request);
            if (response.isSuccess()) {
                //修改订单的状态为已退款
                order.setStatus(AliPayConst.ORDER_REFUND_STATUS);
                //修改订单的退款批次
                order.setBatchNo(refundId);
                iOrderService.updateById(order);

                return ResponseBean.createError("支付宝退款成功");
            } else {

                returnStr = response.getSubMsg();//失败会返回错误信息
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseBean.createSuccess().addData("returnStr",returnStr);
    }





    /**
     *
     * @param out_trade_no    商品订单号
     * @param trade_no        支付宝交易号
     * @param refund_amount    退款金额
     * @return
     */
    @PostMapping("/refundtest")
    public ResponseBean refundtest(String out_trade_no, String trade_no, double refund_amount){

        if((out_trade_no==null||"".equals(out_trade_no))&&(trade_no==null||"".equals(trade_no))){
            return ResponseBean.createError("商品订单号和支付宝交易号不能同时为空");
        }
        String returnStr = null;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String refundId = sdf.format(new Date()) + RandomUtils.makeRandomDigit6() + RandomUtils.getNBitRandomDigit(4);

        String out_request_no = refundId;// 不是全额退款，部分退款使用该参数
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, "RSA2");
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            request.setBizContent("{" +
                    "\"out_trade_no\":\"" + out_trade_no + "\"," +
                    "\"trade_no\":\"" + trade_no + "\"," +
                    "\"refund_amount\":\"" + refund_amount + "\"," +
                    "\"out_request_no\":\"" + out_request_no + "\"," +
                    "\"refund_reason\":\"正常退款\"" +
                    " }");
            AlipayTradeRefundResponse response;
            response = alipayClient.execute(request);
            if (response.isSuccess()) {
                return ResponseBean.createError("支付宝退款成功").addData("退款金额为：",refund_amount);
            } else {

                returnStr = response.getSubMsg();//失败会返回错误信息
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseBean.createSuccess().addData("returnStr",returnStr);
    }



}